package BehaviorPattern.Command;

/**
 * @author: Themberfue
 * @date: 2025/8/13 11:20
 * @description:
 */
// 1. 接收者：各种智能设备
class Light {
    private String location;

    public Light(String location) {
        this.location = location;
    }

    public void on() {
        System.out.println(location + "的灯已打开");
    }

    public void off() {
        System.out.println(location + "的灯已关闭");
    }
}

class TV {
    private String location;

    public TV(String location) {
        this.location = location;
    }

    public void on() {
        System.out.println(location + "的电视已打开");
    }

    public void off() {
        System.out.println(location + "的电视已关闭");
    }

    public void setChannel(int channel) {
        System.out.println(location + "的电视已切换到" + channel + "频道");
    }
}

class AirConditioner {
    private String location;
    int temperature;

    public AirConditioner(String location) {
        this.location = location;
        this.temperature = 26; // 默认温度
    }

    public void on() {
        System.out.println(location + "的空调已打开，当前温度: " + temperature + "°C");
    }

    public void off() {
        System.out.println(location + "的空调已关闭");
    }

    public void setTemperature(int temperature) {
        this.temperature = temperature;
        System.out.println(location + "的空调温度已设置为: " + temperature + "°C");
    }
}

// 2. 抽象命令接口
interface Command {
    void execute();
    void undo(); // 支持撤销操作
}

// 3. 具体命令：灯光命令
class LightOnCommand implements Command {
    private Light light;

    public LightOnCommand(Light light) {
        this.light = light;
    }

    @Override
    public void execute() {
        light.on();
    }

    @Override
    public void undo() {
        light.off();
    }
}

class LightOffCommand implements Command {
    private Light light;

    public LightOffCommand(Light light) {
        this.light = light;
    }

    @Override
    public void execute() {
        light.off();
    }

    @Override
    public void undo() {
        light.on();
    }
}

// 3. 具体命令：电视命令
class TVOnCommand implements Command {
    private TV tv;

    public TVOnCommand(TV tv) {
        this.tv = tv;
    }

    @Override
    public void execute() {
        tv.on();
        tv.setChannel(1); // 默认打开1频道
    }

    @Override
    public void undo() {
        tv.off();
    }
}

// 3. 具体命令：空调命令
class AirConditionerOnCommand implements Command {
    private AirConditioner ac;
    private int previousTemperature; // 用于撤销时恢复温度

    public AirConditionerOnCommand(AirConditioner ac) {
        this.ac = ac;
    }

    @Override
    public void execute() {
        previousTemperature = ac.temperature; // 保存当前温度
        ac.on();
    }

    @Override
    public void undo() {
        ac.off();
    }
}

class SetTemperatureCommand implements Command {
    private AirConditioner ac;
    private int targetTemperature;
    private int previousTemperature; // 用于撤销时恢复

    public SetTemperatureCommand(AirConditioner ac, int targetTemperature) {
        this.ac = ac;
        this.targetTemperature = targetTemperature;
    }

    @Override
    public void execute() {
        previousTemperature = ac.temperature; // 保存当前温度
        ac.setTemperature(targetTemperature);
    }

    @Override
    public void undo() {
        ac.setTemperature(previousTemperature); // 恢复之前的温度
    }
}

// 3. 空命令：用于初始化按钮，避免空指针
class NoCommand implements Command {
    @Override
    public void execute() {}

    @Override
    public void undo() {}
}

// 4. 调用者：遥控器
class RemoteControl {
    private Command[] onCommands;
    private Command[] offCommands;
    private Command undoCommand; // 记录最后执行的命令，用于撤销

    public RemoteControl(int slotCount) {
        onCommands = new Command[slotCount];
        offCommands = new Command[slotCount];

        // 初始化所有命令为空命令
        Command noCommand = new NoCommand();
        for (int i = 0; i < slotCount; i++) {
            onCommands[i] = noCommand;
            offCommands[i] = noCommand;
        }
        undoCommand = noCommand;
    }

    // 设置按钮对应的命令
    public void setCommand(int slot, Command onCommand, Command offCommand) {
        onCommands[slot] = onCommand;
        offCommands[slot] = offCommand;
    }

    // 按下开按钮
    public void pressOnButton(int slot) {
        onCommands[slot].execute();
        undoCommand = onCommands[slot]; // 记录命令用于撤销
    }

    // 按下关按钮
    public void pressOffButton(int slot) {
        offCommands[slot].execute();
        undoCommand = offCommands[slot]; // 记录命令用于撤销
    }

    // 按下撤销按钮
    public void pressUndoButton() {
        System.out.print("撤销操作: ");
        undoCommand.undo();
    }
}

// 5. 客户端代码
public class CommandExample {
    public static void main(String[] args) {
        // 创建接收者（智能设备）
        Light livingRoomLight = new Light("客厅");
        TV livingRoomTV = new TV("客厅");
        AirConditioner bedroomAC = new AirConditioner("卧室");

        // 创建具体命令
        Command livingRoomLightOn = new LightOnCommand(livingRoomLight);
        Command livingRoomLightOff = new LightOffCommand(livingRoomLight);
        Command livingRoomTVOn = new TVOnCommand(livingRoomTV);
        Command livingRoomTVOff = new LightOffCommand(livingRoomLight); // 简化示例，实际应为TVOffCommand
        Command bedroomACOn = new AirConditionerOnCommand(bedroomAC);
        Command setACto24 = new SetTemperatureCommand(bedroomAC, 24);
        Command setACto28 = new SetTemperatureCommand(bedroomAC, 28);

        // 创建调用者（遥控器，有3个插槽）
        RemoteControl remote = new RemoteControl(3);

        // 给遥控器按钮设置命令
        remote.setCommand(0, livingRoomLightOn, livingRoomLightOff);
        remote.setCommand(1, livingRoomTVOn, livingRoomTVOff);
        remote.setCommand(2, bedroomACOn, new LightOffCommand(livingRoomLight)); // 简化示例

        // 测试遥控器操作
        System.out.println("=== 执行一系列操作 ===");
        remote.pressOnButton(0);    // 打开客厅灯
        remote.pressOnButton(1);    // 打开客厅电视
        remote.pressOnButton(2);    // 打开卧室空调
        remote.pressUndoButton();   // 撤销最后操作（关闭卧室空调）

        System.out.println("\n=== 操作空调温度 ===");
        setACto24.execute();        // 设置空调到24度
        setACto28.execute();        // 设置空调到28度
        setACto28.undo();           // 撤销，回到24度
    }
}

